From 1e031cba992894892afdcd42470d840e5b3204e7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timm=20B=C3=A4der?= Date: Fri, 18 Nov 2016 09:29:52 +0100 Subject: [PATCH] widget: Add children and sibling pointers and a (private) way to access them. We will later use these pointers to manage children of non-container widgets and containers alike. --- gtk/gtkwidget.c | 79 ++++++++++++++++++++++++++++++++++++++++++ gtk/gtkwidget.h | 9 +++++ gtk/gtkwidgetprivate.h | 38 ++++++++++++++++++-- 3 files changed, 123 insertions(+), 3 deletions(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 8b52b6c348..91a5d675a4 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -3784,6 +3784,10 @@ gtk_widget_init (GTypeInstance *instance, gpointer g_class) priv->alpha = 255; priv->window = NULL; priv->parent = NULL; + priv->first_child = NULL; + priv->last_child = NULL; + priv->prev_sibling = NULL; + priv->next_sibling = NULL; priv->sensitive = TRUE; priv->redraw_on_alloc = TRUE; @@ -4027,7 +4031,22 @@ gtk_widget_unparent (GtkWidget *widget) priv->child_visible = TRUE; old_parent = priv->parent; + if (old_parent) + { + if (old_parent->priv->first_child == widget) + old_parent->priv->first_child = priv->next_sibling; + + if (old_parent->priv->last_child == widget) + old_parent->priv->last_child = priv->prev_sibling; + + if (priv->prev_sibling) + priv->prev_sibling->priv->next_sibling = priv->next_sibling; + if (priv->next_sibling) + priv->next_sibling->priv->prev_sibling = priv->prev_sibling; + } priv->parent = NULL; + priv->prev_sibling = NULL; + priv->next_sibling = NULL; /* parent may no longer expand if the removed * child was expand=TRUE and could therefore @@ -8395,6 +8414,15 @@ gtk_widget_set_parent (GtkWidget *widget, gtk_widget_push_verify_invariants (widget); priv->parent = parent; + if (parent) + { + priv->prev_sibling = parent->priv->last_child; + if (parent->priv->last_child) + parent->priv->last_child->priv->next_sibling = widget; + parent->priv->last_child = widget; + if (!parent->priv->first_child) + parent->priv->first_child = widget; + } parent_flags = _gtk_widget_get_state_flags (parent); @@ -15655,3 +15683,54 @@ gtk_widget_render (GtkWidget *widget, gsk_renderer_end_draw_frame (renderer, context); } + +GtkWidget * +gtk_widget_get_first_child (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return widget->priv->first_child; +} + +GtkWidget * +gtk_widget_get_last_child (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return widget->priv->last_child; +} + +GtkWidget * +gtk_widget_get_next_sibling (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return widget->priv->next_sibling; +} + +GtkWidget * +gtk_widget_get_prev_sibling (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + return widget->priv->prev_sibling; +} + +void +gtk_widget_forall (GtkWidget *widget, + GtkCallback callback, + gpointer user_data) +{ + GtkWidget *child; + g_return_if_fail (GTK_IS_WIDGET (widget)); + + child = gtk_widget_get_first_child (widget); + while (child) + { + GtkWidget *next = gtk_widget_get_next_sibling (child); + + callback(child, user_data); + + child = next; + } +} diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 151174226e..ed3bfbbfbc 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -1254,6 +1254,15 @@ void gtk_widget_set_font_map (GtkWidget * GDK_AVAILABLE_IN_3_18 PangoFontMap * gtk_widget_get_font_map (GtkWidget *widget); +GDK_AVAILABLE_IN_3_90 +GtkWidget * gtk_widget_get_first_child (GtkWidget *widget); +GDK_AVAILABLE_IN_3_90 +GtkWidget * gtk_widget_get_last_child (GtkWidget *widget); +GDK_AVAILABLE_IN_3_90 +GtkWidget * gtk_widget_get_next_sibling (GtkWidget *widget); +GDK_AVAILABLE_IN_3_90 +GtkWidget * gtk_widget_get_prev_sibling (GtkWidget *widget); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free) diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index aea353434f..c19dd2a966 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -149,12 +149,16 @@ struct _GtkWidgetPrivate GdkWindow *window; GList *registered_windows; - /* The widget's parent */ - GtkWidget *parent; - GList *event_controllers; AtkObject *accessible; + + /* Widget tree */ + GtkWidget *parent; + GtkWidget *prev_sibling; + GtkWidget *next_sibling; + GtkWidget *first_child; + GtkWidget *last_child; }; GtkCssNode * gtk_widget_get_css_node (GtkWidget *widget); @@ -296,6 +300,10 @@ void gtk_widget_adjust_baseline_request (GtkWidget *widget, gint *minimum_baseline, gint *natural_baseline); +void gtk_widget_forall (GtkWidget *widget, + GtkCallback callback, + gpointer user_data); + /* inline getters */ static inline gboolean @@ -406,6 +414,30 @@ _gtk_widget_get_allocation (GtkWidget *widget, *allocation = widget->priv->allocation; } +static inline GtkWidget * +_gtk_widget_get_prev_sibling (GtkWidget *widget) +{ + return widget->priv->prev_sibling; +} + +static inline GtkWidget * +_gtk_widget_get_next_sibling (GtkWidget *widget) +{ + return widget->priv->next_sibling; +} + +static inline GtkWidget * +_gtk_widget_get_first_child (GtkWidget *widget) +{ + return widget->priv->first_child; +} + +static inline GtkWidget * +_gtk_widget_get_last_child (GtkWidget *widget) +{ + return widget->priv->last_child; +} + G_END_DECLS #endif /* __GTK_WIDGET_PRIVATE_H__ */ -- 2.30.2